package com.terracloud.server.controller;

import com.terracloud.server.common.data.DeviceGroup;
import com.terracloud.server.common.data.exception.ThingsboardException;
import com.terracloud.server.common.data.id.DeviceGroupId;
import com.terracloud.server.common.data.id.TenantId;
import com.terracloud.server.common.data.page.PageData;
import com.terracloud.server.common.data.page.PageLink;
import com.terracloud.server.queue.util.TbCoreComponent;
import com.terracloud.server.service.security.permission.Operation;
import com.terracloud.server.vo.DeviceGroupRelationUpdateVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import static com.terracloud.server.controller.ControllerConstants.DEVICE_GROUP_ID;

/**
 *
 * @author chenhainan
 * @since 2025/10/11
 */
@RestController
@TbCoreComponent
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class DeviceGroupController extends BaseController {


    @GetMapping("/deviceGroups")
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    public PageData<DeviceGroup> getDeviceGroups(
            @RequestParam int pageSize,
            @RequestParam int page,
            @RequestParam(required = false) String textSearch,
            @RequestParam(required = false) String sortProperty,
            @RequestParam(required = false) String sortOrder
    ) throws ThingsboardException {
        TenantId tenantId = getCurrentUser().getTenantId();
        PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
        return deviceGroupService.findDeviceGroups(tenantId, pageLink);
    }

    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    @PostMapping(value = "/deviceGroup")
    public DeviceGroup saveDeviceGroup(@RequestBody DeviceGroup deviceGroup) throws ThingsboardException {
        final var currentUser = getCurrentUser();
        deviceGroup.setTenantId(currentUser.getTenantId());
        return deviceGroupService.saveDeviceGroup(deviceGroup, currentUser);
    }

    @GetMapping(value = "/deviceGroup/{deviceGroupId}")
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    public DeviceGroup getDeviceGroup(@PathVariable("deviceGroupId") String strDeviceGroupId) throws ThingsboardException {
        return deviceGroupService.findDeviceGroupInfoById(getCurrentUser().getTenantId(), DeviceGroupId.fromString(strDeviceGroupId));
    }


    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    @DeleteMapping(value = "/deviceGroup/{deviceGroupId}")
    public void deleteDeviceGroup(@PathVariable("deviceGroupId") String strDeviceGroupId) throws ThingsboardException {
        checkParameter(DEVICE_GROUP_ID, strDeviceGroupId);
        final var deviceGroupId = new DeviceGroupId(toUUID(strDeviceGroupId));
        final var deviceGroup = checkDeviceGroupId(deviceGroupId, Operation.DELETE);
        deviceGroupService.delete(deviceGroup, getCurrentUser());
    }


    @PostMapping("/deviceGroup/addDevice")
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    public DeviceGroup addDeviceToGroup(@Validated @RequestBody DeviceGroupRelationUpdateVo deviceGroupRelationUpdateVo) throws ThingsboardException {
        checkDeviceGroupId(new DeviceGroupId(deviceGroupRelationUpdateVo.getDeviceGroupId()), Operation.WRITE);
        deviceGroupService.addDeviceToGroup(getCurrentUser(), deviceGroupRelationUpdateVo);
        return deviceGroupService.findDeviceGroupInfoById(getCurrentUser().getTenantId(), new DeviceGroupId(deviceGroupRelationUpdateVo.getDeviceGroupId()));
    }

    @PostMapping("/deviceGroup/delDevice")
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    public DeviceGroup removeDeviceFromGroup(@Validated @RequestBody DeviceGroupRelationUpdateVo deviceGroupRelationUpdateVo) throws ThingsboardException {
        checkDeviceGroupId(new DeviceGroupId(deviceGroupRelationUpdateVo.getDeviceGroupId()), Operation.WRITE);
        deviceGroupService.removeDeviceFromGroup(getCurrentUser(), deviceGroupRelationUpdateVo);
        return deviceGroupService.findDeviceGroupInfoById(getCurrentUser().getTenantId(), new DeviceGroupId(deviceGroupRelationUpdateVo.getDeviceGroupId()));
    }

}
